import * as THREE from 'three'

import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js';
import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js';
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';

// 在render中执行的定时任务
export class IntervalTime {
    lastTime = 0
    constructor() {
    }
    interval(callback: () => void, time: number) {
        let now = performance.now(); // 使用 performance.now() 获取高精度时间
        let deltaTime = now - this.lastTime;

        if (deltaTime > time) { // 如果已经过了一秒钟
            // 执行一秒内需要做的事情
            callback()
            // 重置时间
            this.lastTime = now;
        }
    }
}

// 创建一个辅助函数，用于检测物体是否在相机视锥体内
export function isObjectInCameraView(object: THREE.Object3D, camera: THREE.Camera): boolean {
    // 获取相机的视锥体
    const frustum = new THREE.Frustum();
    const projectionMatrix = new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
    frustum.setFromProjectionMatrix(projectionMatrix);

    const box3 = new THREE.Box3();
    box3.expandByObject(object);

    const size = new THREE.Vector3();
    const center = new THREE.Vector3()

    const sphere = new THREE.Sphere(center, size.x)
    box3.getBoundingSphere(sphere)

    // 检测物体的边界球体是否在相机视锥体内
    return frustum.intersectsSphere(sphere);
}



const createParams = {
    threshold: 0,
    strength: 0.972, // 强度
    radius: 0.21,// 半径
    exposure: 1.55 // 扩散
};

export const unreal = (scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, width: number, height: number,params=createParams) => {
    // 渲染器通道，将场景全部加入渲染器
    const renderScene = new RenderPass(scene, camera);
    // 添加虚幻发光通道
    const bloomPass = new UnrealBloomPass(new THREE.Vector2(width, height), 1.5, 0.4, 0.85);
    bloomPass.threshold = params.threshold;
    bloomPass.strength = params.strength;
    bloomPass.radius = params.radius;

    // 创建合成器
    const bloomComposer = new EffectComposer(renderer);
    bloomComposer.renderToScreen = false;
    // 将渲染器和场景结合到合成器中
    bloomComposer.addPass(renderScene);
    bloomComposer.addPass(bloomPass);

    // 着色器通道
    const mixPass = new ShaderPass(
        // 着色器
        new THREE.ShaderMaterial({
            uniforms: {
                baseTexture: { value: null },
                bloomTexture: { value: bloomComposer.renderTarget2.texture }
            },
            vertexShader: `
            
            varying vec2 vUv;
    
            void main() {
    
                vUv = uv;
    
                gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    
            }
            
            `,
            fragmentShader: `
            
            uniform sampler2D baseTexture;
            uniform sampler2D bloomTexture;
    
            varying vec2 vUv;
    
            void main() {
    
                gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );
    
            }
    
            `,
            defines: {}
        }), 'baseTexture'
    );
    mixPass.needsSwap = true;

    // 合成器输出通道
    const outputPass = new OutputPass();

    const finalComposer = new EffectComposer(renderer);
    finalComposer.addPass(renderScene);
    finalComposer.addPass(mixPass);
    finalComposer.addPass(outputPass);

    return {
        finalComposer,
        bloomComposer,
        renderScene,
        bloomPass
    }
}